home *** CD-ROM | disk | FTP | other *** search
/ Almathera Ten Pack 2: CDPD 1 / Almathera Ten on Ten - Disc 2: CDPD 1.iso / pd / 201-225 / 214 / mandelvroom / src / lens.c < prev    next >
C/C++ Source or Header  |  1995-03-13  |  14KB  |  574 lines

  1. /*
  2.  * MandelVroom 2.0
  3.  *
  4.  * (c) Copyright 1987,1989  Kevin L. Clague, San Jose, CA
  5.  *
  6.  * All rights reserved.
  7.  *
  8.  * Permission is hereby granted to distribute this program's source
  9.  * executable, and documentation for non-comercial purposes, so long as the
  10.  * copyright notices are not removed from the sources, executable or
  11.  * documentation.  This program may not be distributed for a profit without
  12.  * the express written consent of the author Kevin L. Clague.
  13.  *
  14.  * This program is not in the public domain.
  15.  *
  16.  * Fred Fish is expressly granted permission to distribute this program's
  17.  * source and executable as part of the "Fred Fish freely redistributable
  18.  * Amiga software library."
  19.  *
  20.  * Permission is expressly granted for this program and it's source to be
  21.  * distributed as part of the Amicus Amiga software disks, and the
  22.  * First Amiga User Group's Hot Mix disks.
  23.  *
  24.  * contents: this file contains the code that implements the lens effect
  25.  * (pixelized expansion) when zooming in.
  26.  *
  27.  */
  28.  
  29. #include "mandp.h"
  30.  
  31. /* Lens algorithm:
  32.  *
  33.  *   Initialization - Create RastPort and BitMap as a work area
  34.  *
  35.  *   Lens Expansion -
  36.  *     Phase 1 (Horizontal Expansion)
  37.  *       1.  Working from left side of NavBox to Right
  38.  *       2.  expand one verticle line from NavBox into temp rastport.
  39.  *       3.  duplicate the line in temp rastport to expansion width
  40.  *       4.  Continue for enough lines to fill the temp rastport
  41.  *
  42.  *     Phase 2 (Verticle Expansion)
  43.  *       1.  Working from top of temp rastport to bottom
  44.  *       2.  expand one horizontal line from temp rastport into Lens
  45.  *           window rastport.
  46.  *       3.  duplicate the line in Lens window rastport to expansion height
  47.  *       4.  Continue for enough lines in the temp rastport
  48.  */
  49.  
  50. /* These structures are used to hold horizontally expanded view of lenz
  51.    expansion */
  52.  
  53. static struct RastPort LensRp;
  54. static struct BitMap   LensBitMap;
  55. static LONG   LensWidth, LensHeight;
  56.  
  57. UBYTE LensOK;
  58. UBYTE LensOn = 1;
  59.  
  60. #ifdef TEMPWINDOW
  61. #define SAFEBLIT
  62.  
  63. static struct NewWindow NewTemp = {
  64.    0,12,                     /* start position           */
  65.    80,80,                    /* width, height            */
  66.    (UBYTE) 0, (UBYTE) NORMALPEN,
  67.    MOUSEBUTTONS,             /* IDCMP flags              */
  68.                              /* MandWind flags           */
  69.    WINDOWDRAG | NOCAREREFRESH | SMART_REFRESH,
  70.    (struct Gadget *) NULL,   /* first gadget             */
  71.    (struct Image *) NULL,    /* user checkmark           */
  72.    (UBYTE *) NULL,           /* Title                    */
  73.    (struct Screen *) NULL,   /* pointer to screen        */
  74.    (struct BitMap *) NULL,   /* pointer to superbitmap   */
  75.    20,20,-1,-1,              /* sizing                   */
  76.    CUSTOMSCREEN              /* type of screen           */
  77.    };
  78.  
  79. static struct Window *TempWind;
  80. #endif
  81.  
  82. AllocLensTemp( Pict )
  83.   register struct Picture *Pict;
  84. {
  85.   LONG Plane;
  86.   PLANEPTR t;
  87.  
  88.   extern struct MenuItem LensSub[];
  89.  
  90.   static LensInited;
  91.  
  92.   extern struct NewScreen NewScreen;
  93.  
  94.   if ( !LensOn )
  95.     return;
  96.  
  97.   if (LensOK == 1)
  98.     return;
  99.  
  100.   if (Pict == Pict->DrawPict)
  101.     return;
  102.  
  103. #ifdef TEMPWINDOW
  104.  
  105.   NewTemp.Width    = Pict->Window->Width;
  106.   NewTemp.Height   = Pict->DrawPict->Window->Height;
  107.   NewTemp.LeftEdge = NewScreen.Width - NewTemp.Width-2;
  108.   NewTemp.TopEdge  = 0;
  109.   NewTemp.Screen   = screen;
  110.   TempWind         = OpenWindow( &NewTemp );
  111. /*WindowToBack( TempWind );*/
  112.   LensOK = TempWind != NULL;
  113.  
  114. #else
  115.  
  116.   if ( ! LensInited ) {
  117.  
  118.     InitRastPort( &LensRp );
  119.     LensRp.BitMap = &LensBitMap;
  120.  
  121.     LensInited = 1;
  122.   }
  123.  
  124.   LensWidth  = Pict->Window->Width;
  125.   LensHeight = Pict->DrawPict->Window->Height;
  126.  
  127.   InitBitMap( &LensBitMap, (long) NewScreen.Depth, LensWidth, LensHeight);
  128.  
  129.   for (Plane = 0; Plane < NewScreen.Depth; Plane++) {
  130.  
  131.     t = (PLANEPTR) AllocRaster(LensWidth,LensHeight);
  132.     LensBitMap.Planes[Plane] = (PLANEPTR) t;
  133.  
  134.     if (t == NULL) {
  135.       FreeLensTemp( );
  136.       return;
  137.     }
  138.   }
  139.   LensOK = 1;
  140.  
  141. #endif
  142. }
  143.  
  144. FreeLensTemp( )
  145. {
  146.   LONG Plane;
  147.  
  148.   if (LensOK) {
  149.  
  150. #ifdef TEMPWINDOW
  151.     CloseWindow( TempWind );
  152. #else
  153.  
  154.     for (Plane = 0; Plane < LensBitMap.Depth; Plane++) {
  155.  
  156.       if (LensBitMap.Planes[Plane]) {
  157.  
  158.         FreeRaster( (char *) LensBitMap.Planes[Plane],
  159.                     LensWidth, LensHeight);
  160.         LensBitMap.Planes[Plane] = NULL;
  161.       }
  162.     }
  163. #endif
  164.     LensOK = 0;
  165.   }
  166. }
  167.  
  168. #ifdef SAFEBLIT
  169.  
  170. SafeClipBlit( src_Wind, src_x, src_y,
  171.               dst_Wind, dst_x, dst_y,
  172.               width, height, min_terms,
  173.               line_no )
  174.  
  175.   struct Window *src_Wind, *dst_Wind;
  176.   LONG   src_x, src_y, dst_x, dst_y, width, height, min_terms;
  177.   LONG   line_no;
  178. {
  179.  
  180.   if (src_x < 0 || src_x > src_Wind->Width) {
  181.     printf("Line %d Bad blit src_x %d Width %d\n",
  182.             line_no,src_x,src_Wind->Width);
  183.     return;
  184.   }
  185.  
  186.   if (src_y < 0 || src_y > src_Wind->Height) {
  187.     printf("Line %d Bad blit src_y %d Height %d\n",
  188.             line_no, src_y,src_Wind->Height);
  189.     return;
  190.   }
  191.  
  192.   if (width < 1 || width > src_Wind->Width) {
  193.     printf("Line %d Bad blit width %d\n",line_no, width);
  194.     return;
  195.   }
  196.  
  197.   if (src_x + width > src_Wind->Width) {
  198.     printf("Line %d Blit outside %d Width %d \n",
  199.             line_no,src_x+width,src_Wind->Width);
  200.     return;
  201.   }
  202.  
  203.   if (height < 1 || height > src_Wind->Height) {
  204.     printf("Line %d Bad blit height %d\n",line_no,height);
  205.     return;
  206.   }
  207.  
  208.   if (src_y + height > src_Wind->Height) {
  209.     printf("Line %d Blit outside %d Height %d \n",
  210.             line_no,src_y+height,src_Wind->Height);
  211.     return;
  212.   }
  213.  
  214.   ClipBlit( src_Wind->RPort, src_x, src_y,
  215.             dst_Wind->RPort, dst_x, dst_y,
  216.             width, height, min_terms);
  217. }
  218. #endif
  219.  
  220.   /* Do Lens effect using temporary rastort, ClipBlit() with exponential
  221.      expansion */
  222.  
  223. Lens( Pict )
  224.   register struct Picture *Pict;
  225. {
  226.   struct Picture *DrawPict;
  227.  
  228.   LONG ExpFactor;
  229.   LONG MaxHeight,MaxWidth;
  230.   LONG SrcPos, SrcMax;
  231.  
  232.   LONG DstPos, DstMax;
  233.  
  234.   LONG EOL;
  235.  
  236.   LONG NextPos, AccPos;
  237.   LONG          AccExp;
  238.  
  239.   LONG FirstSrc,FirstDst,NumOnes;
  240.  
  241.   static LONG OldLeft,OldTop,OldExp;
  242.   LONG Top,Left,Bot,t;
  243.  
  244.   struct Window   *src_Wind,*dst_Wind;
  245.   struct RastPort *src_Rp,  *dst_Rp,  *tmp_Rp;
  246.  
  247.   DrawPict = Pict->DrawPict;
  248.  
  249.   if (DrawPict == NULL)
  250.     return;
  251.  
  252.   CloseZoomBoxList( Pict );
  253.  
  254.   src_Wind = DrawPict->Window;
  255.   dst_Wind = Pict->Window;
  256.  
  257.   src_Rp = src_Wind->RPort;
  258.   dst_Rp = dst_Wind->RPort;
  259.  
  260.   if (src_Rp == dst_Rp) return;
  261.  
  262. #ifdef TEMPWINDOW
  263.   tmp_Rp = TempWind->RPort;
  264. #else
  265.   tmp_Rp = &LensRp;
  266. #endif
  267.  
  268.   if ( !LensOK )
  269.     return;
  270.  
  271. #ifndef TEMPWINDOW
  272.   SetRast( tmp_Rp, (long) NORMALPEN );
  273. #endif
  274.  
  275.   /* turn the Nav Box upside down, so the bit map is not inverted */
  276.  
  277.   Top   = Pict->NavTop;
  278.   Bot   = Pict->NavBot;
  279.   Left  = Pict->NavLeft;
  280.  
  281.   if (Bot < Top) {
  282.     t            = Bot;
  283.     Bot = Top;
  284.     Top = t;
  285.   }
  286.   if (Pict->NavRight < Left) {
  287.     Left  = Pict->NavRight;
  288.   }
  289.  
  290.   /* Do Horizontal Expansion into a temporary bitmap */
  291.   /* src = DrawPict */
  292.   /* dst = Pict */
  293.  
  294.   MaxHeight = Bot - Top + 1;
  295.  
  296.   if (MaxHeight == 0)
  297.     return;
  298.  
  299.   DstPos = 0;
  300.  
  301.   DstMax = dst_Wind->Width - Pict->LeftMarg - Pict->RightMarg;
  302.   SrcMax = src_Wind->Width - DrawPict->RightMarg;
  303.  
  304. #define SHIFT_FACTOR 8
  305.  
  306.   AccExp = ((dst_Wind->Height - Pict->TopMarg - Pict->BotMarg)
  307.             << SHIFT_FACTOR) / MaxHeight;
  308.  
  309.   if (OldLeft == Left && OldTop == Top && OldExp == AccExp)
  310.     return;
  311.  
  312.   Pict->Flags |= LENS_DISPLAYED;
  313.  
  314.   OldLeft = Left;
  315.   OldTop  = Top;
  316.   OldExp  = AccExp;
  317.  
  318.   AccPos = DstPos << SHIFT_FACTOR;
  319.  
  320.   EOL = 0;
  321.   NumOnes = 0;
  322.  
  323.   for (SrcPos = Left; SrcPos < SrcMax && ! EOL; SrcPos++) {
  324.  
  325.     AccPos += AccExp;
  326.     NextPos = AccPos >> SHIFT_FACTOR;
  327.  
  328.     ExpFactor = NextPos - DstPos;
  329.  
  330.     /* Accumulate adjacent single line blits */
  331.  
  332.     if (ExpFactor == 1) {
  333.       if (NumOnes == 0) {
  334.         FirstSrc = SrcPos;
  335.         FirstDst = DstPos;
  336.       }
  337.       NumOnes++;
  338.     } else {
  339.  
  340.       /* Copy accumulated adjcent single line copies */
  341.  
  342.       if (NumOnes > 0) {
  343.  
  344. #ifndef SAFEBLIT
  345.         ClipBlit( src_Rp,  FirstSrc,  (long) Top,
  346.                   tmp_Rp,  FirstDst,  0,
  347.                   NumOnes, MaxHeight, (long) 0xc0 );
  348. #else
  349.         SafeClipBlit( src_Wind, FirstSrc,  Top,
  350.                       TempWind, FirstDst,  0,
  351.                       NumOnes,  MaxHeight, 0xc0, __LINE__ );
  352. #endif
  353.         NumOnes = 0;
  354.       }
  355.  
  356.       if (ExpFactor > 1) {
  357.  
  358.         register LONG WrkPos, WrkOff, Last, DstExp;
  359.  
  360.         /* Expand Pattern exponentially */
  361.  
  362.         WrkPos = DstPos + 1;
  363.         WrkOff = 1;
  364.         Last = 0;
  365.         DstExp = 1;
  366.  
  367.         /* Copy First line */
  368.  
  369. #ifndef SAFEBLIT
  370.         ClipBlit( src_Rp, SrcPos,    (long) Top,
  371.                   tmp_Rp, DstPos,    0,
  372.                   (long) 1, MaxHeight, (long) 0xc0 );
  373. #else
  374.         SafeClipBlit( src_Wind,  SrcPos,  Top,
  375.                       TempWind,  DstPos,  0,
  376.                       1,         MaxHeight, 0xc0, __LINE__);
  377. #endif
  378.  
  379.         /* Now expand it exponentially */
  380.  
  381.         do {
  382.  
  383.           if ( WrkOff + DstExp >= ExpFactor ) {
  384.             Last = 1;
  385.             DstExp = ExpFactor - WrkOff;
  386.           }
  387.  
  388.           if ( WrkPos + DstExp >= DstMax ) {
  389.             Last = 1;
  390.             EOL = 1;
  391.             DstExp = DstMax - WrkPos;
  392.           }
  393.  
  394.           if (DstExp) {
  395. #ifndef SAFEBLIT
  396.             ClipBlit( tmp_Rp, DstPos,    0,
  397.                       tmp_Rp, WrkPos,    0,
  398.                       DstExp, MaxHeight, (long) 0xc0 );
  399. #else
  400.             SafeClipBlit( TempWind,  DstPos,  0,
  401.                           TempWind,  WrkPos,  0,
  402.                           DstExp,    MaxHeight, 0xc0, __LINE__);
  403. #endif
  404.             WrkPos += DstExp;
  405.             WrkOff += DstExp;
  406.  
  407.             DstExp <<= 1;
  408.           }
  409.         } while ( ! Last );
  410.       }
  411.     }
  412.     if ((DstPos = NextPos) >= DstMax) EOL = 1;
  413.   }
  414.  
  415.   if (NumOnes > 0) {
  416.  
  417. #ifndef SAFEBLIT
  418.     ClipBlit( src_Rp,  FirstSrc,  (long) Top,
  419.               tmp_Rp,  FirstDst,  0,
  420.               NumOnes, MaxHeight, (long) 0xc0 );
  421. #else
  422.     SafeClipBlit( src_Wind,  FirstSrc,  Top,
  423.                   TempWind,  FirstDst,  0,
  424.                   NumOnes,   MaxHeight, 0xc0, __LINE__);
  425. #endif
  426.   }
  427.   NumOnes = 0;
  428.  
  429.   ZoomBox( Pict );
  430.  
  431.   /* src = DrawPict */
  432.   /* dst = Pict */
  433.  
  434.   /* Do Verticle Expansion */
  435.  
  436.   MaxWidth = dst_Wind->Width - Pict->LeftMarg - Pict->RightMarg;
  437.  
  438.   DstPos = Pict->TopMarg;
  439.   DstMax = dst_Wind->Height - Pict->BotMarg;
  440.   SrcMax = src_Wind->Height;
  441.  
  442.   EOL = 0;
  443.  
  444.   AccPos = DstPos << SHIFT_FACTOR;
  445.  
  446.   for (SrcPos = 0; SrcPos < SrcMax && !EOL; SrcPos++) {
  447.  
  448.     AccPos += AccExp;
  449.     NextPos = AccPos >> SHIFT_FACTOR;
  450.  
  451.     ExpFactor = NextPos - DstPos;
  452.  
  453.     /* Accumulate adjacent single line blits */
  454.  
  455.     if (ExpFactor == 1) {
  456.       if (NumOnes == 0) {
  457.         FirstSrc = SrcPos;
  458.         FirstDst = DstPos;
  459.       }
  460.       NumOnes++;
  461.     } else {
  462.  
  463.       /* Copy accumulated adjacent single line copies */
  464.  
  465.       if (NumOnes > 0) {
  466.  
  467. #ifndef SAFEBLIT
  468.         ClipBlit( tmp_Rp,   0,  FirstSrc,
  469.                   dst_Rp,   Pict->LeftMarg,  FirstDst,
  470.                   MaxWidth, NumOnes,   (long) 0xc0 );
  471. #else
  472.         SafeClipBlit( TempWind,  0,  FirstSrc,
  473.                       dst_Wind,  Pict->LeftMarg,  FirstDst,
  474.                       MaxWidth,  NumOnes,  0xc0, __LINE__);
  475. #endif
  476.         NumOnes = 0;
  477.       }
  478.  
  479.       if ( ExpFactor > 1 ) {
  480.  
  481.         register LONG WrkPos, WrkOff, Last, DstExp;
  482.  
  483.         /* Expand Pattern exponentially */
  484.  
  485.         WrkPos = DstPos + 1;
  486.         WrkOff = 1;
  487.         Last = 0;
  488.         DstExp = 1;
  489.  
  490.         /* Copy First Horizontal Line */
  491.  
  492. #ifndef SAFEBLIT
  493.         ClipBlit( tmp_Rp,   0, SrcPos,
  494.                   dst_Rp,   Pict->LeftMarg, DstPos,
  495.                   MaxWidth, (long) 1, (long) 0xc0 );
  496. #else
  497.         SafeClipBlit( TempWind, 0, SrcPos,
  498.                       dst_Wind, Pict->LeftMarg, DstPos,
  499.                       MaxWidth, 1,        0xc0, __LINE__ );
  500. #endif
  501.         do {
  502.  
  503.           if ( WrkOff + DstExp >= ExpFactor ) {
  504.             Last = 1;
  505.             DstExp = ExpFactor - WrkOff;
  506.           }
  507.  
  508.           if ( WrkPos + DstExp >= DstMax ) {
  509.             Last = 1;
  510.             EOL = 1;
  511.             DstExp = DstMax - WrkPos;
  512.           }
  513.           if (DstExp) {
  514. #ifndef SAFEBLIT
  515.             ClipBlit( dst_Rp,   Pict->LeftMarg, DstPos,
  516.                       dst_Rp,   Pict->LeftMarg, WrkPos,
  517.                       MaxWidth, DstExp,   (long) 0xc0 );
  518. #else
  519.             SafeClipBlit( dst_Wind, Pict->LeftMarg, DstPos,
  520.                           dst_Wind, Pict->LeftMarg, WrkPos,
  521.                           MaxWidth, DstExp,   0xc0, __LINE__ );
  522. #endif
  523.             WrkPos += DstExp;
  524.             WrkOff += DstExp;
  525.  
  526.             DstExp <<= 1;
  527.           }
  528.         } while ( ! Last );
  529.       }
  530.     }
  531.     if ((DstPos = NextPos) >= DstMax) EOL = 1;
  532.   }
  533.  
  534.   /* Copy accumulated adjacent single line copies */
  535.  
  536.   if (NumOnes > 0) {
  537. #ifndef SAFEBLIT
  538.     ClipBlit( tmp_Rp,  0,  FirstSrc,
  539.               dst_Rp,  Pict->LeftMarg,  FirstDst,
  540.               MaxWidth,NumOnes,   (long) 0xc0 );
  541. #else
  542.     SafeClipBlit( TempWind, 0,  FirstSrc,
  543.                   dst_Wind, Pict->LeftMarg,  FirstDst,
  544.                   MaxWidth, NumOnes,   0xc0, __LINE__ );
  545. #endif
  546.   }
  547.  
  548.   ZoomBox( Pict );
  549. }
  550.  
  551. CloseZoomBoxList( Pict )
  552.   register struct Picture *Pict;
  553. {
  554.   register struct Node    *zNode;
  555.   register struct Picture *ClosePict;
  556.            struct Picture *PictAddr();
  557.  
  558.   zNode = Pict->zList.lh_Head;
  559.  
  560.   while ( zNode->ln_Succ ) {
  561.  
  562.     ClosePict = PictAddr( zNode );
  563.  
  564.     if (Pict != ClosePict) {
  565.       CloseZoomBox(ClosePict);
  566.     }
  567.  
  568.     zNode = zNode->ln_Succ;
  569.   }
  570. }
  571.  
  572.  
  573.  
  574.